; void recortar(Uint8* sprite, Uint32 numero_instancia, Uint32 ancho_instancia, Uint32 ancho_sprite, Uint32 alto_sprite, Uint8* instancia, bool orientacion);

; constantes globales

	%include "constantes.mac"

; parametros

	%define sprite				[ebp + 08]
	%define numero_instancia		[ebp + 12]
	%define ancho_instancia			[ebp + 16]
	%define ancho_sprite			[ebp + 20]
	%define alto_sprite			[ebp + 24]
	%define instancia			[ebp + 28]
	%define orientacion			[ebp + 32]

; variables

	%define ancho_sprite_bytes		[ebp - 04]
	%define ancho_instancia_bytes		[ebp - 08]
	%define resto_ancho_sprite_bytes	[ebp - 12]
	%define resto_ancho_instancia_bytes	[ebp - 16]
	%define p_fila				[ebp - 20]
	%define p_columna			[ebp - 24]
	%define p_instancia			[ebp - 28]

	%define bytes_reservados 28

global recortar

section .text

recortar:

	push ebp			; creo el marco de la pila
	mov ebp, esp			; creo el marco de la pila
	sub esp, bytes_reservados	; reservo memoria en la pila
	push ebx			; salvo registros convencion C
	push edi			; salvo registros convencion C
	push esi			; salvo registros convencion C

calculo_ancho_sprite_bytes:

	mov eax, ancho_sprite
	mov ebx, bytes_por_pixel
	mul ebx
	mov ancho_sprite_bytes, eax

calculo_resto:

	mov ebx, 4
	div ebx				; edx = ancho_sprite_bytes % 4
	
	mov resto_ancho_sprite_bytes, edx
				
	cmp edx, 0
	je calcular_ancho_instancia_bytes
	
ajustar_ancho_sprite_bytes:

	mov eax, 4
	sub eax, edx			; eax = (4 - resto)
	add ancho_sprite_bytes, eax	; ancho_sprite_bytes % 4 == 0
	
calcular_ancho_instancia_bytes:

	mov eax, ancho_instancia	; eax = ancho_instancia
	mov ebx, bytes_por_pixel	; ebx = bytes_por_pixel
	mul ebx				; eax = ancho_instancia_bytes
	mov ancho_instancia_bytes, eax
	
calculo_resto_instancia:

	mov ebx, 4
	div ebx				; edx = ancho_instancia_bytes % 4
					
	mov resto_ancho_instancia_bytes, edx
	
calcular_bytes_hasta_primer_columna:
	
	mov eax, ancho_instancia_bytes
	mov ebx, numero_instancia	; ebx = numero_instancia
	mul ebx				; eax = bytes_hasta_primer_columna
	
inicializar_punteros:

	mov ebx, sprite
	add eax, ebx			; eax = bytes_hasta_primer_columna + sprite
	mov p_fila, eax			; p_fila = bytes_hasta_primer_columna + sprite
	mov eax, instancia
	mov p_instancia, eax
	
inicializar_para_cada_fila:

	xor esi, esi			; esi = contador de fila = 0
	
para_cada_fila:

	cmp esi, alto_sprite
	jb entro_fila			; si esi >= alto_sprite termino
	jmp fin
	
entro_fila:

	mov eax, p_fila
	mov p_columna, eax		; p_columna = p_fila
	cmp dword orientacion, 1
	je inicializar_para_cada_columna; si no hay que dar vuelta la imagen empiezo
	
empezar_fila_desde_adelante:

	mov eax, p_columna
	add eax, ancho_instancia_bytes
	sub eax, 3
	mov p_columna, eax		; p_columna = p_fila + ancho_instancia_bytes
	
inicializar_para_cada_columna:

	xor edi, edi			; edi = contador de columna = 0
	
para_cada_columna:

	cmp edi, ancho_instancia
	jae siguiente_fila		; si edi >= ancho_instancia voy a la siguiente fila
	
	mov eax, p_columna
	mov ebx, p_instancia
	mov eax, [eax]
	mov dword [ebx], eax
	
siguiente_columna:
	
	mov eax, p_instancia
	add eax, bytes_por_pixel
	mov p_instancia, eax		; avanzo puntero instancia un pixel
	
	mov eax, p_columna
	add eax, bytes_por_pixel
	mov p_columna, eax		; avanzo puntero columna un pixel
	
	inc edi
	
	cmp dword orientacion, 0
	je volver_columna_atras		; si no hay que dar vuelta la imagen empiezo
	jmp para_cada_columna
	
volver_columna_atras:

	mov eax, p_columna
	sub eax, 6
	mov p_columna, eax		; p_columna-= 6
	jmp para_cada_columna
	
siguiente_fila:
	
	inc esi
	
	mov eax, ancho_sprite_bytes
	add p_fila, eax			; p_fila+= ancho_sprite_bytes
	
	mov eax, resto_ancho_instancia_bytes
	cmp eax, 0
	je para_cada_fila
	
	mov ebx, 4
	sub ebx, eax
	add p_instancia, ebx
	
	jmp para_cada_fila

fin:

	pop esi				; desarmo el stack frame
	pop edi				; desarmo el stack frame
	pop ebx				; desarmo el stack frame
	add esp, bytes_reservados	; desarmo el stack frame
	pop ebp				; desarmo el stack frame

	ret
